package com.briup.proxy.jdk;

import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;

//理解、能看懂源码即可，不要求强制记忆
//日志代理工具类
public class LogProxyFactory {
    //对外接口：传入目标对象，动态生成代理对象并返回
    public static <T> T getProxy(T target) {
        //1.获取目标对象所属类的字节码对象
        Class<?> c = target.getClass();

        //2.准备目标对象类加载器对象、接口数组
        ClassLoader classLoader = c.getClassLoader();
        Class<?>[] interfaces = c.getInterfaces();
        //准备InvocationHandler接口的实现类对象
        InvocationHandler h =
                new MyInvocationHandler(target);

        //3.使用JDK动态代理生成代理对象
        T proxy = (T) Proxy.newProxyInstance(classLoader, interfaces, h);

        return proxy;
    }

    //静态成员内部类
    private static class MyInvocationHandler
                        implements InvocationHandler {
        //目标对象
        private Object target;

        public MyInvocationHandler(Object target) {
            this.target = target;
        }

        //重写方法：实现目标对象基本核心功能的基础上，添加附加功能
        @Override
        public Object invoke(Object proxy,
                             Method method,
                             Object[] args) throws Throwable {
            //获取目标对象类名
            String className = target.getClass().getName();
            //获取核心方法名
            String methodName = method.getName();

            //核心方法执行前 日志输出
            System.out.println(className+" 类型对象中的 "+
                                    methodName+" 方法即将执行...");

            //执行目标对象核心方法
            Object result = method.invoke(target, args);

            //核心方法执行后 日志输出
            System.out.println(className+" 类型对象中的 "+
                    methodName+" 方法执行完毕!");

            //返回核心方法执行结果
            return result;
        }
    }
}
